from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from erp_system.models import PermissionsModel, RolesModel
from erp_system.serializers.permission_serializer import PermissionsSerializer

import logging

logger = logging.getLogger('my')

class PermissionViewSet(ModelViewSet):
    """
     create:
    权限--新增

    权限新增, status: 201(成功), return: 新增权限信息

    destroy:
    权限--删除

    权限删除, status: 204(成功), return: None

    multiple_delete:
    权限--批量删除,必传参数：ids=[1,2,3,4...]

    权限批量删除, status: 204(成功), return: None

    update:
    权限--修改

    权限修改, status: 200(成功), return: 修改增权限信息

    partial_update:
    权限--局部修改

    权限局部修改, status: 200(成功), return: 修改增权限信息

    list:
    权限--获取所有的权限

    find_permissions_by_menu:
    获取当前菜单的所有权限设置 列表,必传参数：menu_id

    例如：http://127.0.0.1:8000/permissions/find_permissions_by_menu/?menu_id=2
    权限列表信息, status: 200(成功), return: 权限信息列表

    find_permissions:
    打开授权页面的时候，首先请求的接口；获取当前角色已经授予的权限ID列表和整个项目的所有权限(树形)列表,必传参数：rid(角色ID)

    例如：http://127.0.0.1:8000/permissions/find_permissions/?rid=2
    树形权限列表信息, status: 200(成功), return: 权限信息列表
    retrieve:
    查询某一个指定的权限信息

    查询指定ID的权限, status: 200(成功), return: 权限信息

    """

    queryset = PermissionsModel.objects.all()
    serializer_class = PermissionsSerializer

    # 定义好了一个swagger的参数
    menu_param = openapi.Parameter(name='menu_id', in_=openapi.IN_QUERY, description='所选的菜单ID',
                                   type=openapi.TYPE_INTEGER)

    @swagger_auto_schema(method='GET', manual_parameters=[menu_param], operation_description='单一授权或者取消单一权限')
    @action(methods=['GET'], detail=False)
    def find_permissions_by_menu(self, request, *args, **kwargs):
        menu_id = request.query_params.get('menu_id')
        permission_list = PermissionsModel.objects.filter(menu__id=menu_id).all()
        return Response(data=self.get_serializer(instance=permission_list, many=True).data)

    # 定义好了一个swagger的参数
    menu_param2 = openapi.Parameter(name='rid', in_=openapi.IN_QUERY, description='所选的角色ID',
                                    type=openapi.TYPE_INTEGER)

    @swagger_auto_schema(method='GET', manual_parameters=[menu_param2])
    @action(methods=['GET'], detail=False)
    def find_permissions(self, request, *args, **kwargs):
        #  获取当前角色已经授予的权限ID列表和整个项目的所有权限(树形)列表
        result = {}  # 返回的整个字典数据，
        rid = request.query_params.get('rid', None)
        if rid:  # 查询当前角色的所有已经授权的ID
            ids = RolesModel.objects.filter(id=rid).values_list('permissions', flat=True).distinct()
            result['ids'] = ids  # 存入返回字典中

        # 整个ERP系统中，所有权限列表，而且要树形展示
        permissions_list = PermissionsModel.objects.values('id', 'name', 'menu__parent__id', 'menu__name', 'menu__id')
        tree_dict = {}  # 一个父节点权限（里面是树形嵌套）
        tree_data = []  # 所有权限 ，
        """
        [
            {父节点1的内容，children=[{子节点内容}，{子节点内容}...]},
            {父节点2的内容，children=[{子节点内容}，{子节点内容}...]},
            ...
        ]
        """
        # 第一步构建一颗二级树
        for item in permissions_list:
            tree_dict[item['menu__id']] = item
        for i in tree_dict:
            if tree_dict[i]['menu__parent__id']:  # 表示子权限
                pid = tree_dict[i]['menu__parent__id']
                parent = tree_dict[pid]
                child = dict()  # 创建一个空字典(二级)，第二级只要：menu__id, menu__name, permissions(权限列表)
                child['menu__id'] = tree_dict[i]['menu__id']
                child['menu__name'] = tree_dict[i]['menu__name']
                child.setdefault('permissions', [])
                parent.setdefault('children', []).append(child)
            else:
                tree_data.append(tree_dict[i])

        # 第二步：在前面二级树形结构的基础上，添加子权限。得到三级树
        for parent in tree_data:
            if 'children' in parent:
                for child in parent['children']:
                    for node in permissions_list:
                        if node['menu__parent__id'] and node['menu__id'] == child['menu__id']:
                            child['permissions'].append(node)
        logger.info(tree_data)
        result['tree_data'] = tree_data  # 把三级树结构，加入到结果中
        return Response(result)
